<template>
  <div class="goods-list">
    <div class="mask" v-if="showMask" @click="hiddenHandle"></div>

    <!-- 商品类型 -->
    <div class="goods-list-left">
      <van-sidebar v-model="activeKey">
        <van-sidebar-item
          :title="goods.mealType.mealType"
          v-for="(goods, index) in goodsList"
          :key="index"
          :badge="accountTypeNumber(goods.mealType.mealTypeId) === 0 ? '' : accountTypeNumber(goods.mealType.mealTypeId)"
        />
      </van-sidebar>
    </div>
    <!-- if语句判断变量activeKey按对应index跳转 -->
    <div class="goods-list-right" v-if="pitchGoodsArr[0]">
      <recursion-goods :goodsArr="pitchGoodsArr"></recursion-goods>
    </div>
    <!-- 显示遮罩层 -->
    <van-overlay :show="show" z-index="9999">
      <div class="wrapper" v-if="show">
        <div class="wrapper-top">
          <h4>{{ isActiveGoods.mealName }}</h4>
          <div class="block">
            <van-image
              class="van-image"
              width="10rem"
              height="10rem"
              fit="contain"
              :src="isActiveGoods.mealPictures[0]"
            />
            <h5>销量{{ isActiveGoods.mealSales }} | 好评率100%</h5>
            <van-icon size="30" name="close" @click="show = false" />
          </div>
        </div>
      </div>
    </van-overlay>
    <!-- 购物车 -->
    <div class="shop-card-box">
      <div class="shop-card">
        <div class="no-choise" v-if="billList.length === 0">
          <div class="card-icon">
            <van-icon name="shopping-cart-o" color="#1989fa" size="30px" />
          </div>
          <span class="text">请选择商品</span>
        </div>
        <div class="having-choise" v-else>
          <div class="card-icon" @click="showShopCar">
            <van-badge :content="billCount">
              <van-icon name="shopping-cart-o" color="#1989fa" size="30px" />
            </van-badge>
          </div>
          <div class="price-total">{{ billTotal }}￥</div>
          <div class="go-account" @click="goAccountHandle">去结算</div>
        </div>
      </div>
    </div>
    <!-- 购物车展开 -->
    <div class="show-shop-car animate__animated" v-show="showMask">
      <div class="shop-car">已选商品</div>
      <div class="bill-goods-box">
        <goods-item
          v-for="goods in billList"
          :key="goods.mealId"
          :goods="goods"
          @billIsNull="hiddenHandle"
        ></goods-item>
      </div>
    </div>
  </div>
</template>

<script>
import recursionGoods from "./recursion-goods.vue";
import goodsItem from "./goods-item.vue";
import { mapState } from "vuex";
import { getMenu } from '@/api/homeApi';
export default {
  name: "goodsList",
  components: {
    recursionGoods,
    goodsItem,
  },
  created() {
    this.getGoodList();
  },
  data() {
    return {
      activeKey: 0,
      show: false,
      goodsList: [], // 总的商品列表
      // pitchGoodsArr: [], // 选中类型对应的商品集合
      isActiveGoods: {},
      showMask: false,
    };
  },
  methods: {
    hiddenHandle() {
      this.showMask = false;
    },
    async getGoodList() {
      /**
       * 坑点:
       *  由于在这个组件的created里调用了getGoodList() 里面有个网络请求并且使用了await, 因此运行到这await的时候会将这个函数挂起,
       *  接着会去执行子组件的beforeCreate created beforeMounte mounted 接着才会去事件循环监听, 先看有没有微任务, 再去根据浏览器对任务类型队列的优先级依次去排查有没有任务需要调用
       *  在这里它会看到网络请求队列中是否任务, 这里有个网络请求结束后对回调函数封装成了一个任务, 所以渲染主线程就会去调用它, 然后继续await往下执行
       */
      // let { data: res } = await this.$http.get("/restaurant-meal/meal/menu"); // 网络请求完成后, 将回调函数封装成一个网络请求任务, 但是这个任务不是放到微任务队列里面的
      let res = await getMenu();
      if(res.code === 200 && res.success) {
        this.goodsList = res.data;
      } 
    },
    goAccountHandle() {
      // 判断是否登录, 如果没有登录则提示登录
      if (Object.keys(this.userInfo).length <= 0) {
        // 说明是空对象
        this.$toast.fail("请先登录");
      } else {
        // 说明已经登录
        this.$router.push({
          path: "/settle",
          query: {
            billInfo: this.billList,
          },
        });
      }
    },
    activeGoodsHandle(goods) {
      this.show = true;
      this.isActiveGoods = goods;
    },
    // 展示购物车
    showShopCar() {
      this.showMask = true;
    },
  },
  computed: {
    ...mapState("m_user", ["billList", "userInfo"]),
    billTotal() {
      let total = this.billList.reduce((init, goods) => {
        return init + goods.mealPrice * goods.buyCount;
      }, 0);
      return Number(Number(total).toFixed(2));
    },
    billCount() {
      let count = this.billList.reduce((init, goods) => {
        return init + goods.buyCount;
      }, 0);
      return count;
    },
    // 左侧分类的选择总数标记
    accountTypeNumber() {
      return function(bigTypeId) {
        let count = this.billList.reduce((amt, item) => {
          if(item.mealTypeId === bigTypeId) {
            return amt + item.buyCount
          } else {
            return amt
          }
        }, 0);
        return count;
      }
    },
    // 选中类型对应的商品集合, 根据activeKey的变化而重新计算
    pitchGoodsArr() {
      return [this.goodsList[this.activeKey]]
    }
  },
};
</script>

<style lang="scss" scoped>
.mask {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background-color: rgba(0, 0, 0, 0.3);
  z-index: 10;
}
.goods-list {
  position: relative;
  display: flex;
  height: 100%;
  box-sizing: border-box;
  padding-bottom: 65px;
  margin-top: 8px;
}
/* 商品类型 */
.goods-list-left {
  height: 100%;
  overflow: auto;
}
/* 商品内容 */
.goods-list-right {
  /* margin: right; */
  width: 78%;
  height: 100%;
  flex-grow: 1; // 占用剩余部分
  overflow: auto;
}

/* 遮罩层 */
.wrapper {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}
.wrapper-top {
  width: 200px;
  height: 210px;
  background-color: white;
  position: relative;
}

.block {
  position: absolute;
  left: 20px;
}
.block > i {
  color: #fff;
  margin: 20px 0 30px 65px;
}

.wrapper-top > h4 {
  font-size: 15px;
  color: #000;
}
.block > h5 {
  color: gray;
  font-size: 8px;
  padding-top: 2px;
  font-weight: 100;
}

/* 购物车 */
.shop-card-box {
  display: flex;
  justify-content: center;
  align-items: center;
  position: absolute;
  left: 50%;
  bottom: 0;
  transform: translateX(-50%);
  height: 65px;
  width: 100%;
  z-index: 20;
}
.shop-card {
  display: flex;
  align-items: center;
  position: absolute;
  width: 80%;
  height: 50px;
  background-color: #000;
  border-radius: 30px;
  overflow: hidden;
}
.no-choise {
  display: flex;
  align-items: center;
}
.card-icon {
  margin: 0 25px;
}
.text {
  color: #ccc;
  font-size: 12px;
}
.having-choise {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  height: 100%;
}
.price-total {
  display: flex;
  align-items: center;
  flex-grow: 1;
  color: #fff;
  font-weight: 700;
  font-size: 18px;
}
.having-choise .card-icon {
  margin: 0 10px;
}
.go-account {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  width: 30%;
  background-color: rgb(30, 189, 252);
  color: #fff;
  font-weight: 700;
}

// 购物车展开
.show-shop-car {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  // height: 300px;
  background-color: #fff;
  padding-bottom: 100px;
  z-index: 15;

  .shop-car {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 10px;
    width: 100%;
    height: 40px;
    background: #f6f6f6;
    color: #7d7d7d;
    font-size: 12px;
  }

  .bill-goods-box {
    max-height: 400px;
    // height: 400px;
    overflow: auto;
  }
}

.btn-box {
  display: flex;
  justify-content: flex-end;
}
div[class$="-btn"] {
  display: flex;
  justify-content: center;
  align-content: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background-color: rgb(30, 189, 252);
  font-size: 18px;
  color: #fff;
  box-sizing: border-box;
}
div.subtrat-btn {
  background-color: #fff;
  border: 1px solid #ccc;
  color: #ccc;
  line-height: 16px;
}

.buy-count {
  line-height: 20px;
  margin: 0 5px;
}

::v-deep .van-sidebar-item {
  padding: 15px 12px;
}
</style>
